#include <seqlist.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

vector* new_vector(unsigned capicity) {
    vector* ptr = (vector*)malloc(sizeof(vector) + capicity * sizeof(int));
    if (NULL == ptr) {
        return NULL;
    }
    ptr->capicity = capicity;
    ptr->length = 0;
    return ptr;
}

unsigned int vector_length(const vector* list) {
    assert(list != NULL);
    return list->length;
}

void vector_for_each(vector* list, vector_visitor visitor) {
    assert(list != NULL);
    for (int i = 0; i < list->length; i++) {
        visitor(list->data[i]);
    }
}

vector* vector_insert(vector* list, int val, int position) {
    assert(list != NULL);
    // 空表，直接放到第一个位置，忽略位置参数
    if (vector_empty(list)) {
        list->data[0] = val;
        list->length += 1;
        return list;
    }

    // 判断下标是否合法
    position -= 1;
    if (position < 0 || position >= list->length) {
        return list;
    }

    // 扩容
    if (list->length == list->capicity) {
        vector* new_list = new_vector(list->capicity * 2);
        new_list->length = list->length;
        // 迁移元素
        for (int i = 0; i < list->length; i++) {
            new_list->data[i] = list->data[i];
        }
        // 释放旧的列表
        vector_release(list);
        list = new_list;
    } 
    // 在列表最后插入的情况
    if (position == list->length - 1) {
        list->data[position + 1] = val;
        list->length += 1;
        return list;
    } 
    // 在列表中间位置插入的情况，需要搬迁元素，腾出位置
    for (int i = list->length - 1; i > position; i--) {
        list->data[i + 1] = list->data[i];
    }
    list->data[position + 1] = val;
    list->length += 1;

    return list;
}

int vector_remove(vector* list, int position) {
    assert(list != NULL && position >= 1 && position <= list->length);
    position -= 1;
    // 移除最后一个元素，不需要搬迁，直接改变顺序表长度即可
    if (position == list->length - 1) {
        list->length -= 1;
        return list->data[position];
    }
    // 移除中间元素，需要搬迁
    int ret = list->data[position];
    for (int i = position + 1; i < list->length; i++) {
        list->data[i - 1] = list->data[i];
    }
    list->length -= 1;
    return ret;
}

vector* vector_append(vector *list, int val) {
    assert(list != NULL);
    return vector_insert(list, val, list->length);
}

void vector_release(vector* list) {
    if (NULL != list) {
        free(list);
    }
}

int vector_empty(vector* list) {
    return 0 == list->length;
}

/**
 * 访问链表的第position个位置的元素
 * @param position 元素位置
 */
int vector_get_at(vector* list, int position) {
    assert(list != NULL && position >= 1 && position <= list->length);
    return list->data[position - 1];
}

/**
 * 修改链表的第position个位置的元素
 * @param position 元素位置
 */
void vector_set_at(vector *list, int val, int position) {
    assert(list != NULL && position >= 1 && position <= list->length);
    list->data[position - 1] = val;
}